<template>
  <div class="role-management">
    <!-- 搜索表单 -->
    <BaseForm
      ref="searchFormRef"
      v-model:formData="searchFormData"
      :form-list="searchFormList"
      :inline="true"
      label-position="right"
      class="search-form"
    >
      <template #button>
        <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-button @click="handleReset">重置</el-button>
        <el-button type="success" @click="handleAdd">新增</el-button>
      </template>
    </BaseForm>

    <!-- 角色表格 -->
    <CommonTable :tableData="tableData" :columns="tableColumns" :loading="loading" border>
      <template #opt="{ row }">
        <el-button size="small" type="primary" @click="handleEdit(row)">编辑</el-button>
        <el-button size="small" type="warning" @click="handleAssignMenus(row)">菜单权限</el-button>
        <el-button size="small" type="danger" @click="handleDelete(row)">删除</el-button>
      </template>
    </CommonTable>

    <!-- 分页 -->
    <Pagination
      v-model="pagination"
      @update:modelValue="handlePageChange"
      :page-sizes="[10, 20, 50, 100]"
    />

    <!-- 角色编辑对话框 -->
    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      width="600px"
      @close="handleDialogClose"
    >
      <BaseForm
        ref="roleFormRef"
        v-model:formData="roleFormData"
        :form-list="roleFormList"
        :rules="roleFormRules"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSave">保存</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 菜单权限对话框 -->
    <el-dialog title="分配菜单权限" v-model="menuDialogVisible" width="600px">
      <el-tree
        ref="menuTreeRef"
        :data="menuTreeData"
        :props="menuTreeProps"
        node-key="id"
        show-checkbox
        :default-checked-keys="defaultCheckedKeys"
        :default-expand-all="true"
        :check-strictly="false"
        :expand-on-click-node="false"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="menuDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSaveMenus">保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { changeTree } from "@/utils";
import BaseForm from "@/components/Form/BaseForm.vue";
import CommonTable from "@/components/Table/CommonTable.vue";
import Pagination from "@/components/Pagination/Pagination.vue";
import roleApi from "@/api/system/role";
import menuApi from "@/api/system/menu";
import menu from "@/api/system/menu";

// 搜索表单引用
const searchFormRef = ref<InstanceType<typeof BaseForm> | null>(null);
// 角色表单引用
const roleFormRef = ref<InstanceType<typeof BaseForm> | null>(null);

// 搜索表单数据
const searchFormData = reactive({
  roleName: "",
  roleCode: "",
});

// 搜索表单配置
const searchFormList = [
  {
    key: "roleName",
    tag: "el-input",
    label: "角色名称",
    props: {
      placeholder: "请输入角色名称",
      clearable: true,
    },
  },
  {
    key: "roleCode",
    tag: "el-input",
    label: "角色编码",
    props: {
      placeholder: "请输入角色编码",
      clearable: true,
    },
  },
];

// 表格列配置
const tableColumns = [
  {
    label: "角色名称",
    prop: "roleName",
  },
  {
    label: "角色编码",
    prop: "roleCode",
  },
  {
    label: "描述",
    prop: "description",
  },
  {
    label: "创建时间",
    prop: "createTime",
    width: 180,
  },
  {
    label: "更新时间",
    prop: "updateTime",
    width: 180,
  },
  {
    label: "操作",
    width: 250,
    props: {
      fixed: "right",
    },
  },
];

// 表格数据
const tableData = ref([]);
// 加载状态
const loading = ref(false);
// 分页数据
const pagination = reactive({
  page: 1,
  limit: 10,
  total: 0,
});

// 对话框相关
const dialogVisible = ref(false);
const dialogTitle = ref("");
const isEdit = ref(false);

// 角色表单数据
const roleFormData = reactive({
  id: undefined,
  roleName: "",
  roleCode: "",
  description: "",
});

// 角色表单配置
const roleFormList = [
  {
    key: "roleName",
    tag: "el-input",
    label: "角色名称",
    required: true,
    props: {
      placeholder: "请输入角色名称",
    },
  },
  {
    key: "roleCode",
    tag: "el-input",
    label: "角色编码",
    required: true,
    props: {
      placeholder: "请输入角色编码",
    },
  },
  {
    key: "description",
    tag: "el-input",
    label: "描述",
    props: {
      type: "textarea",
      placeholder: "请输入描述",
      rows: 3,
    },
  },
];

// 角色表单验证规则
const roleFormRules = {
  roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  roleCode: [{ required: true, message: "请输入角色编码", trigger: "blur" }],
};

// 菜单权限对话框相关
const menuDialogVisible = ref(false);
const currentRoleId = ref<string>("");
const menuTreeData = ref<SysMenu[]>([]);
const menuTreeProps = {
  children: "children",
  label: "menuName",
};
const defaultCheckedKeys = ref<string[]>([]);

// 菜单树引用
const menuTreeRef = ref();

// 页面初始化
onMounted(() => {
  fetchRoleList();
});

// 获取角色列表
const fetchRoleList = async () => {
  loading.value = true;
  try {
    const params = {
      ...searchFormData,
      page: pagination.page,
      limit: pagination.limit,
    };
    const res: any = await roleApi.page(params);
    tableData.value = res.records;
    pagination.total = res.total;
  } catch (error) {
  } finally {
    loading.value = false;
  }
};

// 搜索
const handleSearch = () => {
  pagination.page = 1;
  fetchRoleList();
};

// 重置搜索
const handleReset = () => {
  searchFormRef.value?.resetForm();
  pagination.page = 1;
  fetchRoleList();
};

// 分页变化
const handlePageChange = (val: any) => {
  pagination.page = val.page;
  pagination.limit = val.limit;
  fetchRoleList();
};

// 新增角色
const handleAdd = () => {
  isEdit.value = false;
  dialogTitle.value = "新增角色";
  // 重置表单数据
  Object.assign(roleFormData, {
    id: undefined,
    roleName: "",
    roleCode: "",
    description: "",
  });
  dialogVisible.value = true;
};

// 编辑角色
const handleEdit = (row: any) => {
  isEdit.value = true;
  dialogTitle.value = "编辑角色";
  // 填充表单数据
  Object.assign(roleFormData, {
    id: row.id,
    roleName: row.roleName,
    roleCode: row.roleCode,
    description: row.description,
  });
  dialogVisible.value = true;
};

// 保存角色
const handleSave = async () => {
  try {
    await roleFormRef.value?.checkValidate();

    if (isEdit.value) {
      // 编辑
      await roleApi.update(roleFormData);
      ElMessage.success("更新成功");
      dialogVisible.value = false;
      fetchRoleList();
    } else {
      // 新增
      await roleApi.add(roleFormData);
      ElMessage.success("新增成功");
      dialogVisible.value = false;
      fetchRoleList();
    }
  } catch (error) {}
};

// 关闭对话框
const handleDialogClose = () => {
  roleFormRef.value?.resetForm();
};

// 删除角色
const handleDelete = (row: any) => {
  ElMessageBox.confirm(`确定要删除角色"${row.roleName}"吗？`, "确认删除", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      try {
        await roleApi.delete(row.id);
        ElMessage.success("删除成功");
        fetchRoleList();
      } catch (error) {}
    })
    .catch(() => {
      // 取消删除
    });
};

// 处理分配菜单权限
const handleAssignMenus = async (row: any) => {
  currentRoleId.value = row.id.toString();
  await fetchMenuTree();
  await fetchRoleMenus(row.id);
  menuDialogVisible.value = true;
};

// 在 fetchMenuTree 方法中添加数据转换逻辑
const fetchMenuTree = async () => {
  try {
    const res: any = await menuApi.list();
    menuTreeData.value = changeTree(res, 0) as any;
  } catch (error) {}
};

// 获取角色已分配的菜单
const fetchRoleMenus = async (roleId: number) => {
  try {
    // 先清空已选菜单
    menuTreeRef.value?.setCheckedKeys([]);
    defaultCheckedKeys.value = [];
    const res: any = await roleApi.getMenusByRoleId(roleId);

    // 获取所有叶子节点的key（即没有子菜单的节点）
    const getAllLeafNodeKeys = (nodes: any[]): string[] => {
      let keys: string[] = [];
      nodes.forEach((node) => {
        // 如果是叶子节点（没有children或children为空数组）
        if (!node.children || node.children.length === 0) {
          keys.push(node.id.toString());
        } else {
          // 递归处理子节点
          keys = keys.concat(getAllLeafNodeKeys(node.children));
        }
      });
      return keys;
    };

    // 转换为树形结构
    const tree = changeTree(res, 0);

    // 获取所有叶子节点的key
    const allKeys = getAllLeafNodeKeys(tree);

    // 设置默认选中的keys
    defaultCheckedKeys.value = allKeys;

    // 设置树节点的选中状态
    menuTreeRef.value?.setCheckedKeys(allKeys);
  } catch (error) {
    console.error("获取角色已分配的菜单失败:", error);
  }
};
// 保存菜单权限
const handleSaveMenus = async () => {
  try {
    // 获取选中的菜单节点
    const checkedKeys = [
      ...menuTreeRef.value?.getHalfCheckedKeys(),
      ...menuTreeRef.value?.getCheckedKeys(),
    ];
    await roleApi.assignMenus(currentRoleId.value, checkedKeys);
    ElMessage.success("菜单权限分配成功");
    menuDialogVisible.value = false;
  } catch (error) {}
};
</script>

<style scoped lang="scss">
.role-management {
  padding: 20px;
}

.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
}

.dialog-footer {
  text-align: right;
}
</style>
